/******************************************************************************************************
Copyright (C) 2012 Mestrelab Research S.L. All rights reserved.

This file is part of the Mnova scripting toolkit.

Authorized users of MNova Software may use this file freely, but this file is provided AS IS
with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE.
*****************************************************************************************************/
/*globals settings, Dir, MessageBox, CommonSlots, qsTr, File, Process, TextStream, MnUi, print, qsTr, FileDialog*/
/*jslint plusplus: true, continue: true, bitwise: true*/

function PythonUtils() {
	"use strict";

	this.PythonPathKey = "Python Utils/Python Intallation Path";
	this.Python = settings.value(this.PythonPathKey, "");
	this.scriptsDir = Dir.application() + "/scripts";
	this.tempDir = Dir.home();
	this.isActive = true;

	if (!this.checkPythonInstallation()) {
		if (!this.setup()) {
			this.isActive = false;
		}
	}
}

PythonUtils.prototype.getPythonVersion = function (aVersion) {
	"use strict";
	if (aVersion) {
		aVersion = aVersion.replace("Python ", "");
		return aVersion[0];
	}
	return 0;

};

PythonUtils.prototype.checkPythonInstallation = function () {
	"use strict";

	var pythonDir, tempArray = [], proc, message;

	if (!this.Python || this.Python === "") {
		return false;
	}

	pythonDir = new Dir(this.Python);
	if (!pythonDir.exists) {
		return false;
	}

	tempArray = pythonDir.entryList("python*");

	if (tempArray.length === 0) {
		return false;
	}

	proc = new Process();
	proc.start(pythonDir.absPath + '/python', ['--version']);
	proc.waitForFinished(1000);

	message = proc.allErrorOutput;

	if (this.getPythonVersion(message) < 3) {
		return false;
	}

	return true;
};


PythonUtils.prototype.setup = function () {
	"use strict";


	var i, j, pythonDirCandidate, pythonDir, tempArray, path, splittingChar,
		standardDir = "C:/Python",
		environment = Process.systemEnvironment().toString();

	//Enviroment search

	if (environment.indexOf("ython") !== -1) {

		path = environment.substring(environment.indexOf("Path") + "Path=".length, environment.indexOf(",", environment.indexOf("Path")));

		if (environment.indexOf("OS=Win") !== -1) {
			splittingChar = ";";
		} else {
			splittingChar = ":";
		}

		path = path.split(splittingChar);

		for (i = 0; i < path.length; i++) {
			if (path[i].indexOf("ython") !== -1) {
				pythonDir = new Dir(path[i]);
				if (pythonDir.exists) {
					tempArray = pythonDir.entryList("python*");
					if (tempArray.length !== 0) {
						this.Python = pythonDir.absPath;
						if (this.checkPythonInstallation()) {
							settings.setValue(this.PythonPathKey, this.Python);
							return true;
						}
					}

				}
			}
		}

	}


	//standard dir search
	for (i = 2; i < 10; i++) {
		for (j = 0; j < 10; j++) {
			pythonDirCandidate = standardDir + i + j;
			pythonDir = new Dir(pythonDirCandidate);
			if (pythonDir.exists) {
				tempArray = pythonDir.entryList("python*");
				if (tempArray.length !== 0) {
					this.Python = pythonDir.absPath;
					if (this.checkPythonInstallation()) {
						settings.setValue(this.PythonPathKey, this.Python);
						return true;
					}
				}
			}
		}
	}

	//manual search
	MessageBox.information(qsTr("Mnova was unable to find Python 3.\n If Python 3 is installed please select the installation directory otherwise please install Python 3 and restart Mnova"));
	pythonDirCandidate  = FileDialog.getExistingDirectory(Dir.home(), "Select Python installation folder");

	if (pythonDirCandidate && pythonDirCandidate !== "") {
		pythonDir = new Dir(pythonDirCandidate);
		if (pythonDir.exists) {
			tempArray = pythonDir.entryInfoList("python*");
			if (tempArray.length !== 0) {
				this.Python = pythonDir.absPath;
				if (this.checkPythonInstallation()) {
					settings.setValue(this.PythonPathKey, this.Python);
					return true;
				}
			}
		}
	}
	return false;

};


PythonUtils.prototype.toString = function () {
	"use strict";
	return "PythonUtils()";
};


PythonUtils.prototype.executeScriptV3 = function (aFile, aParameters) {
	"use strict";

	//To keep compatibility with previous versions
	print("executeScriptV3 is obsolete. Use executeScript instead");

	return this.executeScript(aFile, aParameters);
};

PythonUtils.prototype.executeScript = function (aFile, aParameters) {
	"use strict";

	var code, executable = this.Python + "/python";
	code = this.execute(aFile, aParameters, executable);
	return code;
};

PythonUtils.prototype.execute = function (aFile, aParameters, aPythonExecutable) {
	"use strict";
	var i, code, scriptsDir = new Dir(this.scriptsDir),
		scriptFile = new File(scriptsDir.filePath(aFile)),
		cmd = [];
	cmd.push(scriptFile.name);
	for (i = 0; i < aParameters.length; i++) {
		cmd.push(aParameters[i]);
	}

	code = Process.execute(aPythonExecutable, cmd);
	return code;
};

PythonUtils.prototype.request = function (aURL, aAction, aResponseFileName) {
	"use strict";
	var tempDir = new Dir(this.tempDir),
		scriptFile = "ricares:request.py",
		responseFile = new File(tempDir.filePath(aResponseFileName)),
		parameters = [],
		code;

	parameters.push(aURL);
	parameters.push(aAction);
	parameters.push(responseFile.name);
	code = this.executeScriptV3(scriptFile, parameters);

	if (code >= 0) {
		return code;
	}
	throw "Error in Python executable: " + code;
};

PythonUtils.prototype.request2XML = function (aURL, aAction) {
	"use strict";
	var sin, xml, code, responseFile,
		responseFileName = "response.xml",
		tempDir = new Dir(this.tempDir);

	code = this.request(aURL, aAction, responseFileName);

	if (code === 0) {
		responseFile = new File(tempDir.filePath(responseFileName));
		responseFile.open(File.ReadOnly);
		sin = new TextStream(responseFile);
		xml = sin.readAll();
		sin.flush();
		responseFile.close();
		File.remove(responseFile.name);
		return xml;
	}
	File.remove(responseFile.name);

};

PythonUtils.prototype.soapRequest = function (aURL, aAction, aSearch, aSoapResponseFileName) {
	"use strict";
	var soapRequestTxt,
		parameters = [],
		tempDir = new Dir(this.tempDir),
		soapRequest = "soapRequest.xml",
		scriptFile = "ricares:soapRequest.py",
		soapResponseFile = new File(tempDir.filePath(aSoapResponseFileName)),
		soapRequestFile = new File(tempDir.filePath(soapRequest));

	soapRequestFile.open(File.WriteOnly);
	soapRequestTxt = new TextStream(soapRequestFile);
	soapRequestTxt.write(aSearch);
	soapRequestTxt.flush();
	soapRequestFile.close();

	parameters.push(aURL);
	parameters.push(aAction);
	parameters.push(soapRequestFile.name);
	parameters.push(soapResponseFile.name);

	this.executeScriptV3(scriptFile, parameters);
	File.remove(soapRequestFile.name);

	return soapResponseFile;
};

PythonUtils.prototype.soapRequest2XML = function (aURL, aAction, aSearch) {
	"use strict";

	var sin, xml, soapResponseFileName = "soapResponse.xml",
		soapResponseFile = this.soapRequest(aURL, aAction, aSearch, soapResponseFileName);

	soapResponseFile.open(File.ReadOnly);
	sin = new TextStream(soapResponseFile);
	xml = sin.readAll();
	sin.flush();
	soapResponseFile.close();
	File.remove(soapResponseFile.name);
	return xml;

};


